package com.smart.controller;


import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.smart.pojo.LoginUser;
import com.smart.pojo.ResultBean;
import com.smart.pojo.User;
import com.smart.pojo.UserRole;
import com.smart.req.AssociateUserRole;
import com.smart.req.LoginUserData;
import com.smart.req.PageData;
import com.smart.req.UserCondition;
import com.smart.resp.UserResp;
import com.smart.service.IUserService;
import com.smart.utils.SMUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author lyj
 * @since 2023-04-19
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserService userService;

    /**
     * 获取验证码
     *
     * @param session
     * @return
     */
    @GetMapping("getCode")
    public ResultBean getCode(HttpSession session) {
        //定义图形验证码的长、宽、验证码字符数、干扰元素个数
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);
        //将验证码保存到session
        session.setAttribute("okCode", captcha.getCode());
        //返回前端验证码图片
        return ResultBean.success(captcha.getImageBase64Data());
    }

    /**
     * 用户登录认证
     *
     * @param loginUserData
     * @param session
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/login")
    public ResultBean login(@RequestBody LoginUserData loginUserData,
                            HttpSession session,
                            HttpServletRequest request,
                            HttpServletResponse response) {
        //判断cookie是否存在账号信息，存在则用cookie登录
        Subject subject = SecurityUtils.getSubject();
        //创建登录令牌
        UsernamePasswordToken token = new UsernamePasswordToken();
        //获取cookies
        Cookie[] cookies = request.getCookies();
        //是否设置自动登录
        boolean rememberMe = false;

        if (loginUserData.getUserCode() == null) {
            //遍历cookies获取账号密码
            for (Cookie cookie : cookies) {
                if (cookie.getName().equalsIgnoreCase("usercode")) {
                    System.out.println("cookie中的账号：" + cookie.getValue());
                    token.setUsername(cookie.getValue());
                }
                if (cookie.getName().equalsIgnoreCase("password")) {
                    System.out.println("cookie中的密码：" + cookie.getValue());
                    token.setPassword(cookie.getValue().toCharArray());
                }
            }
            rememberMe = true;
        } else {
            //判断验证码是否正确
            String okCode = (String) session.getAttribute("okCode");
            if (!okCode.equalsIgnoreCase(loginUserData.getCode())) {
                System.out.println("验证码" + loginUserData.getCode() + "错误，正确验证码为" + okCode);
                return ResultBean.error("验证码错误");
            }

            token.setUsername(loginUserData.getUserCode());
            token.setPassword(loginUserData.getPassword().toCharArray());
            rememberMe = loginUserData.isRememberMe();
        }

        //登录认证
        subject.login(token);

        //判断是否登陆成功
        if (subject.isAuthenticated()) {
            //判断是否设置自动登录
            if (rememberMe) {
                //添加账号和密码的Cookie
                Cookie usercode = new Cookie("usercode", token.getUsername());
                usercode.setPath("/");
                usercode.setMaxAge(604800);  //保留7天
                Cookie password = new Cookie("password", new String(token.getPassword()));
                password.setPath("/");
                password.setMaxAge(604800);  //保留7天
                response.addCookie(usercode);
                response.addCookie(password);
            } else {
                //删除账号和密码的cookie
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equalsIgnoreCase("usercode") || cookie.getName().equalsIgnoreCase("password")) {
                        cookie.setMaxAge(0);
                        cookie.setPath("/");
                        response.addCookie(cookie);
                    }
                }
            }
            //返回登录主体
            return ResultBean.success(subject.getPrincipal());

        } else {
            System.out.println("登陆失败");
            return ResultBean.error("账号或密码错误，请重新登陆");
        }
    }

    /**
     * 根据条件进行分页查询
     *
     * @param userCondition
     * @return
     */
    @GetMapping("queryPageByCondition")
    public ResultBean queryByPageAndCondition(UserCondition userCondition) {
        System.out.println("分页条件查询用户条件：" + userCondition);
        Page<UserResp> userPage = new Page<>(userCondition.getPageNum(), userCondition.getPageSize());
        userService.queryPageByCondition(userCondition, userPage);
        return ResultBean.success(userPage);
    }

    @GetMapping("queryByDeptId")
    public ResultBean queryByDeptId(PageData pageData, Long departmentId) {
        System.out.println("查询用户的部门Id：" + departmentId);
        Page<UserResp> userPage = new Page<>(pageData.getPageNum(), pageData.getPageSize());
        userService.queryPageByDeptId(departmentId, userPage);
        return ResultBean.success(userPage);
    }

    /**
     * 新增或修改用户数据
     *
     * @param user
     * @return
     */
    @PostMapping("/saveOrUpdate")
    @RequiresPermissions({"user:saveOrUpdate"})
    public ResultBean saveOrUpdate(@RequestBody User user) {
        System.out.println("新增或修改的用户数据：" + user);
//        if (user.getId() == null) {
//            //设置初始默认用户状态为入职
//            user.setStatus(0);
//            //设置初始默认密码123
//            user.setPassword(new Md5Hash("123", user.getUserCode(), 3).toString());
//            //生成唯一工号
//            user.setWorkNum(SMUtils.getWorkNum(userService.getCountByToday()));
//        }
        boolean rs = userService.saveOrUpdateUser(user);
        return rs ? ResultBean.success() : ResultBean.error();
    }

    /**
     * 逻辑删除用户
     */
    @DeleteMapping("/deleteById/{id}")
    @RequiresPermissions({"user:dismissed"})
    public ResultBean deleteById(@PathVariable("id") Long id) {
        System.out.println("要删除用户的Id:" + id);
        boolean rs = userService.removeById(id);
        return rs ? ResultBean.success() : ResultBean.error();
    }

    /**
     * 根据Id辞退用户
     */
    @GetMapping("/dismissedById/{id}")
    @RequiresPermissions({"user:dismissed"})
    public ResultBean dismissedById(@PathVariable("id") Long id) {
        System.out.println("要辞退用户的Id:" + id);
        boolean rs = userService.dismissedById(id);
        return rs ? ResultBean.success() : ResultBean.error();
    }

    /**
     * 获取全部用户
     */
    @GetMapping("/queryAll")
    public ResultBean queryAll() {
        return ResultBean.success(userService.list());
    }

    /**
     * 根据角色Id与关键字信息查找在职用户
     */
    @GetMapping("queryByRoleIdAndKeyword")
    public ResultBean queryByRoleIdAndKeyword(Long roleId, String keyword) {
        System.out.println("查找用户的角色Id：" + roleId + ",关键字为：" + keyword);
        return ResultBean.success(userService.queryByRoleIdAndKeyword(roleId, keyword));
    }

//    /**
//     * 查找指定角色以外以及符合条件的用户
//     */
//    @GetMapping("queryByKeywordExcludeRoleId")
//    public ResultBean queryByKeywordExcludeRoleId(Long roleId, String keyword){
//        System.out.println("查找用户排除的角色Id：" + roleId + ",关键字为：" + keyword);
//        return ResultBean.success(userService.queryByKeywordExcludeRoleId(roleId,keyword));
//    }

    /**
     * 查找未分配角色以及符合条件的用户
     */
    @GetMapping("queryByKeywordExcludeRole")
    public ResultBean queryByKeywordExcludeRole(String keyword) {
        System.out.println("查找用户关键字为：" + keyword);
        return ResultBean.success(userService.queryByKeywordExcludeRole(keyword));
    }

    /**
     * 用户关联角色信息
     *
     * @param associateUserRole
     * @return
     */
    @PostMapping("associate")
    @RequiresPermissions({"role:associate"})
    public ResultBean associate(@RequestBody AssociateUserRole associateUserRole) {
        System.out.println("关联的用户角色信息：" + associateUserRole);
        boolean rs = userService.associate(associateUserRole.getRoleId(), associateUserRole.getUserIds());
        return rs ? ResultBean.success() : ResultBean.error();
    }

    /**
     * 用户解除角色关联
     *
     * @param userId
     * @return
     */
    @GetMapping("cancelAssociate/{userId}")
    @RequiresPermissions({"role:associate"})
    public ResultBean cancelAssociate(@PathVariable("userId") Long userId) {
        System.out.println("取消关联的用户id：" + userId);

        boolean rs = userService.lambdaUpdate()
                .eq(User::getId, userId)
                .set(User::getRoleId, null)
                .update();

        return rs ? ResultBean.success() : ResultBean.error();
    }

    /**
     * 查询指定ID用以及未关联角色的用户
     */
    @GetMapping("queryThisUserAndNotAssociateUser")
    public ResultBean queryThisUserAndNotAssociateUser(Long userId) {
        System.out.println("指定的用户ID：" + userId);
        List<User> userList = userService.lambdaQuery()
                .eq(!ObjectUtils.isEmpty(userId), User::getId, userId)
                .or()
                .isNull(User::getRoleId)
                .list();
        return ResultBean.success(userList);
    }

    /**
     * 修改用户头像
     */
    @GetMapping("switchAvatar")
    public ResultBean switchAvatar(Long id, String headPicture) {
        System.out.println("修改头像的用户ID" + id + ",头像地址：" + headPicture);
        User byId = userService.getById(id);
        byId.setPic(headPicture);
        boolean rs = userService.updateById(byId);
        return rs ? ResultBean.success(byId) : ResultBean.error();
    }

    @GetMapping("getUserInfo/{userId}")
    public ResultBean getUserInfo(@PathVariable("userId") Long userId) {
        System.out.println("获取用户详情的Id:" + userId);
        UserResp userResp = userService.getUserInfoById(userId);
        return ResultBean.success(userResp);
    }

    @GetMapping("resetPassword")
    public void updatePassword() {
        List<User> list = userService.list();
        for (User user : list) {
            Md5Hash md5Hash = new Md5Hash("123", user.getUserCode(), 3);
            user.setPassword(md5Hash.toString());
        }
        userService.updateBatchById(list);
    }

    @PostMapping("updatePassword")
    public ResultBean updatePassword(@RequestBody Map<String, String> map) {
        System.out.println("新旧密码：");
        map.forEach((k, v) -> System.out.println(k + ":" + v));
        String oldPassword = map.get("oldPassword");
        String newPassword = map.get("newPassword");
        User user = userService.getById(map.get("id"));
        if (user.getPassword().equals(new Md5Hash(oldPassword, user.getUserCode(), 3).toString())) {
            user.setPassword(new Md5Hash(newPassword, user.getUserCode(), 3).toString());
            boolean rs = userService.updateById(user);
            return rs ? ResultBean.success() : ResultBean.error();
        } else {
            return ResultBean.error("原始密码错误，请检查");
        }

    }
}
